package com.mmall.order.service;

import com.common.framework.constant.Constants;
import com.common.framework.constant.DeleteStatus;
import com.common.framework.util.CollectionUtilPlus;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.mmall.common.spring.service.IDGenerateService;
import com.mmall.order.api.bo.OrderBO;
import com.mmall.order.api.constant.OrderItemStatus;
import com.mmall.order.api.constant.OrderStatus;
import com.mmall.order.api.dto.OrderCreateDTO;
import com.mmall.order.api.service.OrderService;
import com.mmall.order.convert.OrderConvert;
import com.mmall.order.convert.OrderItemConvert;
import com.mmall.order.dao.OrderItemMapper;
import com.mmall.order.dao.OrderMapper;
import com.mmall.order.helper.OrderNumberGenerateHelper;
import com.mmall.order.model.OrderDO;
import com.mmall.order.model.OrderItemDO;
import com.mmall.product.api.bo.ProductBO;
import com.mmall.product.api.service.ProductService;
import com.mmall.user.api.bo.UserAddressBO;
import com.mmall.user.api.service.UserAddressService;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author hejianglong
 * @date 2019/10/23
 */
@Component
@Service(version = "1.0.0")
public class OrderServiceImpl implements OrderService {

    // ------- 本地引用 --------
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private IDGenerateService idGenerateService;

    @Autowired
    private OrderNumberGenerateHelper orderNumberGenerateHelper;

    // ------- 远程引用 --------
    @Reference(version = "1.0.0")
    private UserAddressService userAddressService;

    @Reference(version = "1.0.0")
    private ProductService productService;

    @Override
    @Transactional
    public void createOrder(@NotNull Long userId, OrderCreateDTO orderCreateDTO) {
        OrderDO orderDO = new OrderDO();
        List<OrderItemDO> orderItemDOS = OrderItemConvert.INSTANCE.convert(orderCreateDTO.getOrderItems());
        UserAddressBO userAddressBO = userAddressService.getUserAddress(orderCreateDTO.getUserAddressId());
        Preconditions.checkNotNull(userAddressBO, "没有找到对应的物流信息: userAddressId: ".concat(String.valueOf(orderCreateDTO.getUserAddressId())));

        // 查询订单下面的所有商品
        Set<Long> productIds = orderItemDOS.stream().map(OrderItemDO::getProductId).collect(Collectors.toSet());
        List<ProductBO> productBOS = productService.findProducts(productIds);
        Preconditions.checkArgument((CollectionUtilPlus.isNotEmpty(productBOS) && productIds.size() == productBOS.size()),
                Joiner.on(Constants.DEFAULT_SPLIT).join(productIds).concat(" :需要购买的商品数据变动下单失败"));
        Map<Long, ProductBO> productBOMap = productBOS.stream().collect(Collectors.toMap(ProductBO::getId, productBO -> productBO));

        // 生成订单号
        final Long orderNum = orderNumberGenerateHelper.generateOrderNumber();

        Integer orderTotalAmount = 0;
        final long orderId = idGenerateService.generateID();

        // 生成 orderItem 订单
        for (OrderItemDO orderItemDO: orderItemDOS) {
            ProductBO productBO = productBOMap.get(orderItemDO.getProductId());
            // 如果有优惠价的话按照优惠价购买
            Integer itemBuyPrice = productBO.getPrice();
            if (productBO.getDiscountPrice() != null && productBO.getDiscountPrice() > 0) {
                itemBuyPrice = productBO.getDiscountPrice();
            }
            Integer totalAmount = itemBuyPrice * orderItemDO.getQuantity();
            orderTotalAmount += totalAmount;
            final long orderItemId = idGenerateService.generateID();
            orderItemDO.setOrderId(orderId)
                .setBuyerId(userId)
                .setSellerId(productBO.getUserId())
                .setHammerPrice(itemBuyPrice)
                .setOriginPrice(productBO.getPrice())
                .setOrderNumber(orderNum)
                .setTotalAmount(totalAmount)
                .setStatus(OrderItemStatus.WAIT_SEND)
                .setDeleted(DeleteStatus.ACTIVE)
                .setId(orderItemId);
            orderItemMapper.insert(orderItemDO);
        }

        // 保存订单基本信息
        orderDO.setReceiverAddress(userAddressBO.getAddress())
            .setBuyerId(userId)
            .setReceiverArea(userAddressBO.getArea())
            .setReceiverMobile(userAddressBO.getMobile())
            .setReceiverName(userAddressBO.getName())
            .setOrderNumber(orderNum)
            .setStatus(OrderStatus.WAIT_PAY)
            .setTotalAmount(orderTotalAmount)
            .setLogisticsPrice(0)
            .setDeleted(DeleteStatus.ACTIVE)
            .setId(orderId);
        orderMapper.insert(orderDO);
    }

    @Override
    public OrderBO getOrder(Long orderId) {
        OrderDO orderDO = orderMapper.selectById(orderId);
        return OrderConvert.INSTANCE.convert(orderDO);
    }

    @Override
    public void paySuccess(long orderId) {
        OrderDO orderDO = orderMapper.selectById(orderId);
        Preconditions.checkNotNull(orderDO, "没有找到对应的订单信息: orderId: ".concat(String.valueOf(orderId)));
        orderDO.setPaymentTime(new Date()).setStatus(OrderStatus.WAIT_SEND);
        orderMapper.updateById(orderDO);
    }
}
